-
Notifications
You must be signed in to change notification settings - Fork 3
Change parsing of duration to humantime #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
chore: * update gitignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Greptile Summary
Overview
This PR replaces manual duration parsing with the humantime crate to fix issue #38. The changes improve code maintainability by leveraging an established library rather than implementing custom duration parsing logic.
Core Changes
- Dependency Addition: Added
humantime = { version = "2.3.0" }to handle duration parsing - Function Replacement: Removed custom
parse_duration()function and updatedparse_expiry()to use humantime's parser - Error Handling: Added
HumantimeParseerror variant to properly surface parsing errors - Formatting Consistency: Reformatted Cargo.toml dependencies to use consistent struct syntax
Positive Aspects
- ✅ Eliminates custom parsing code in favor of a battle-tested library
- ✅ Humantime supports more flexible duration formats (e.g., "1d2h30m" vs just "1d")
- ✅ Proper error handling with descriptive error messages
- ✅ Maintains backward compatibility with Unix timestamp parsing
- ✅ No breaking changes to public API
Concerns
1. Unrelated Changes Included
The PR includes gitignore changes (config file pattern rename) that are not related to the stated purpose of duration parsing. This violates the principle of focused commits and makes review harder.
2. Missing Test Coverage
The removed parse_duration() function had no explicit tests, but now that the duration parsing logic is inlined in parse_expiry(), there should be dedicated tests for:
- Relative duration parsing (e.g., "+30d", "+2h")
- Edge cases and invalid inputs
- Compatibility with various humantime format strings
3. Mixed Formatting and Functional Changes
Cargo.toml contains both stylistic changes (consistent dependency formatting) and functional changes (adding humantime). These should ideally be separate commits.
Technical Assessment
- The humantime integration is correct and properly converts to
std::time::Duration - Error mapping is appropriate with the new
HumantimeParseerror variant - The
#[allow(clippy::cast_possible_wrap)]attribute onparse_expiryis correct as it handles the i64 conversion from system time - All function signatures remain compatible with existing callers
Commit Quality
The PR violates the custom instruction rule requiring "logical, independent commits that each build and pass unit tests". This is a single commit mixing:
- Core feature change (humantime integration)
- Styling/formatting changes (Cargo.toml dependency format consistency)
- Unrelated configuration changes (gitignore updates)
Confidence Score: 3/5
- This PR is safe to merge from a functional standpoint with minor concerns about test coverage and commit structure
- Score of 3 reflects: (1) Core functionality is sound and the humantime integration is correct (+), (2) No breaking changes to public API (+), (3) However, there are organizational issues that violate commit structure rules (-), unrelated gitignore changes that lack justification (-), missing test coverage for the new parse_expiry implementation (-), and mixed formatting/functional changes (-). The code itself would work, but the PR structure and completeness need improvement before merging.
- .gitignore (needs clarification on why config file pattern changed), crates/cli-client/src/cli/interactive.rs (needs test coverage for parse_expiry)
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| crates/cli-client/Cargo.toml | 5/5 | Added humantime dependency (2.3.0) and reformatted existing dependencies for consistency. No functional issues detected. |
| crates/cli-client/src/error.rs | 5/5 | Added HumantimeParse error variant with proper error message formatting. Error handling integrates well with existing error types. |
| crates/cli-client/src/cli/interactive.rs | 4/5 | Replaced custom duration parsing with humantime crate. Core functionality improved but missing test coverage for the new parse_expiry implementation. Error messages slightly changed but remain functional. |
| .gitignore | 2/5 | Unrelated changes to gitignore patterns that conflict with the PR's stated purpose. Changes update config file pattern and add duplicate .env entry but lack documentation. |
Sequence Diagram
sequenceDiagram
participant CLI as CLI Code
participant PE as parse_expiry()
participant HT as humantime::Duration
participant Err as Error Handling
CLI->>PE: Input: expiry string ("+30d" or "1609459200")
alt Unix Timestamp
PE->>PE: parse::<i64>()
PE-->>CLI: Return i64 (success)
else Relative Duration
PE->>PE: strip_prefix('+')
PE->>HT: parse::<humantime::Duration>()
alt Parse Success
HT-->>PE: humantime::Duration
PE->>PE: Convert to std::time::Duration
PE->>PE: Calculate: now + duration.as_secs()
PE-->>CLI: Return i64 (success)
else Parse Failure
HT-->>Err: DurationError
Err-->>PE: Error::HumantimeParse
PE-->>CLI: Return Error (failure)
end
else No Match
PE-->>CLI: Error::Config (invalid format)
end
Additional Comments (1)
Consider adding test cases to verify:
Example test structure: #[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_expiry_unix_timestamp() {
// Test unix timestamp parsing
}
#[test]
fn test_parse_expiry_relative_duration() {
// Test relative duration parsing with humantime
}
}Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time! Prompt To Fix With AIThis is a comment left during a code review.
Path: crates/cli-client/src/cli/interactive.rs
Line: 209:231
Comment:
The `parse_expiry` function was previously testable through its `parse_duration` helper, but now that `parse_duration` has been removed and the logic is inlined using the humantime crate, there are no tests for the new implementation.
Consider adding test cases to verify:
1. Parsing Unix timestamps still works (e.g., "1609459200")
2. Parsing durations with humantime works (e.g., "+30d", "+2h", "+1w", "+5m30s")
3. Invalid formats are properly rejected
4. Edge cases like "+0s" or very large durations are handled
Example test structure:
```rust
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_parse_expiry_unix_timestamp() {
// Test unix timestamp parsing
}
#[test]
fn test_parse_expiry_relative_duration() {
// Test relative duration parsing with humantime
}
}
```
<sub>Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!</sub>
How can I resolve this? If you propose a fix, please make it concise. |
0372867 to
60aa87b
Compare
|
@greptile review the PR according to the CONTRIBUTION.md |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Greptile Overview
Greptile Summary
Summary
This PR replaces the manual duration parsing logic with the humantime crate, addressing issue #38. The changes include:
-
Main Implementation Change (commit e836a8e): Replaced the custom
parse_durationfunction withhumantime::Durationparsing in theparse_expiryfunction. The new implementation supports more flexible duration formats (e.g., "+30d", "+2h", "+1w", "+45min", "+1d2h"). -
Dependency Updates (commit 60aa87b):
- Added
humantime2.3.0 dependency - Updated workspace dependencies:
contractsandcli-helperrevision to "94993a0",simplicityhl-coreversion to 0.3.4 - Updated
crates/signer/src/lib.rsto usehash_scriptinstead ofhash_script_pubkey(breaking API change in dependency)
- Added
-
Test Coverage: Added 9 new test cases covering:
- Unix timestamp parsing (including zero and large values)
- Relative duration parsing (days, hours, weeks, minutes, combined units)
- Error cases (invalid formats, invalid durations, negative durations)
Architecture
The implementation maintains backward compatibility by still supporting Unix timestamp input, while extending functionality to accept relative durations with the + prefix. Error handling properly propagates humantime parsing errors through a new HumantimeParse error variant.
Concerns
-
Test Timing Race Condition: The new tests contain a potential timing issue where two
current_timestamp()calls within a test could span a second boundary, causing assertion failures. While unlikely in practice, the tests could be more robust. -
Commit Structure: The PR follows a good logical commit structure with independent, self-contained changes.
Confidence Score: 3/5
- PR is safe to merge after addressing the flaky test implementation, which could fail under rare timing conditions.
- The PR successfully implements the intended feature (replacing manual duration parsing with humantime) and includes comprehensive test coverage. However, the new test cases have a potential race condition between two
current_timestamp()calls that could cause tests to fail if a second boundary is crossed between calls. While this is unlikely in practice, it represents a code quality issue that should be addressed before merging. The dependency updates appear consistent with the functionality changes. The commit structure is logical and follows best practices. - crates/cli-client/src/cli/interactive.rs - The test cases for parse_expiry (lines 479-517) should be refactored to avoid the timing race condition.
Important Files Changed
File Analysis
| Filename | Score | Overview |
|---|---|---|
| crates/cli-client/src/cli/interactive.rs | 3/5 | Replaced manual duration parsing with humantime crate. Tests added for parse_expiry function but may have timing issues due to race condition between multiple current_timestamp() calls. |
| crates/cli-client/src/error.rs | 5/5 | Added HumantimeParse error variant to handle duration parsing errors from humantime crate. Properly formatted error message with both the input string and error details. |
| crates/cli-client/Cargo.toml | 5/5 | Added humantime 2.3.0 dependency and reformatted dependency entries for consistency. No issues identified. |
| crates/signer/src/lib.rs | 4/5 | Updated import and function call from hash_script_pubkey to hash_script, passing address.script_pubkey() instead. Appears to match version update in workspace dependencies. |
Sequence Diagram
sequenceDiagram
participant User
participant parse_expiry
participant humantime
participant current_timestamp
User->>parse_expiry: parse_expiry("+30d")
Note over parse_expiry: Try parse as i64
alt Not a valid i64
parse_expiry->>parse_expiry: Check for '+' prefix
alt Has '+' prefix
parse_expiry->>humantime: parse::<humantime::Duration>("30d")
humantime-->>parse_expiry: Duration(2592000s)
parse_expiry->>current_timestamp: Get current time
current_timestamp-->>parse_expiry: now (seconds since epoch)
parse_expiry->>parse_expiry: now + 2592000s
parse_expiry-->>User: Ok(expiry_timestamp)
else No '+' prefix
parse_expiry-->>User: Err(Config("Invalid expiry format..."))
end
else Valid i64
parse_expiry-->>User: Ok(timestamp)
end
chore: * add some tests for parse_expiry * fix hash script dependency error
60aa87b to
8f51664
Compare
|
@greptile review the PR according to the CONTRIBUTION.md |
Greptile OverviewGreptile SummaryThis PR replaces manual duration parsing with the Key ChangesDuration Parsing Enhancement:
Dependency Updates:
API Migration:
Testing:
Minor Changes:
Functional ImpactThe change is backward compatible for existing usage patterns while adding new capabilities. Users can continue using the old format ( Confidence Score: 4/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User
participant CLI as CLI Command
participant ParseExpiry as parse_expiry()
participant Humantime as humantime crate
participant Timestamp as current_timestamp()
User->>CLI: Provide expiry string (e.g., "+30d" or "1704067200")
CLI->>ParseExpiry: parse_expiry(expiry_str)
alt Unix Timestamp Format
ParseExpiry->>ParseExpiry: Try parse as i64
ParseExpiry-->>CLI: Return timestamp
else Relative Duration Format (starts with '+')
ParseExpiry->>ParseExpiry: Strip '+' prefix
ParseExpiry->>Timestamp: Get current time
Timestamp-->>ParseExpiry: current_timestamp (i64)
ParseExpiry->>Humantime: Parse duration string
alt Valid Duration
Humantime-->>ParseExpiry: Duration object
ParseExpiry->>ParseExpiry: Convert to seconds (u64)
ParseExpiry->>ParseExpiry: Cast to i64 (with cast_possible_wrap)
ParseExpiry->>ParseExpiry: Add to current timestamp
ParseExpiry-->>CLI: Return future timestamp
else Invalid Duration
Humantime-->>ParseExpiry: DurationError
ParseExpiry-->>CLI: Return Error::HumantimeParse
end
else Invalid Format
ParseExpiry-->>CLI: Return Error::Config
end
CLI->>CLI: Use timestamp for contract expiry
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 file reviewed, 1 comment
KyrylR
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK 5a16582
5a16582 to
dc44856
Compare
|
Required label not found on this PR. |
Replace manual duration parsing with humantime
Fixes #38 and dependency issue highlighted by
cargo clippy.Examples of strings to parse can be found here https://docs.rs/humantime/latest/humantime/fn.parse_duration.html.